/*!
 * \file trader_api.cpp
 * \project AI_CTP
 * 
 * \brief CTP交易API实现 - 基于wt_ctp成功实现
 */

#include "trader_api.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <chrono>
#include <algorithm>

namespace ctp_api {

TraderApi::TraderApi() 
    : api_(nullptr)
    , state_(TradeState::DISCONNECTED)
    , front_id_(0)
    , session_id_(0)
    , request_id_(0)
    , order_ref_(0)
    , stop_query_thread_(false)
    , total_orders_(0)
    , total_trades_(0)
{
}

TraderApi::~TraderApi() {
    release();
}

bool TraderApi::init(const std::string& broker_id, const std::string& user_id, 
                     const std::string& password, const std::string& app_id,
                     const std::string& auth_code, const std::vector<std::string>& front_addresses,
                     const std::string& flow_path) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 设置参数
    broker_id_ = broker_id;
    user_id_ = user_id;
    password_ = password;
    app_id_ = app_id.empty() ? "simnow_client_test" : app_id;
    auth_code_ = auth_code.empty() ? "0000000000000000" : auth_code;
    
    if (front_addresses.empty()) {
        front_addresses_ = {"tcp://180.168.146.187:10130"}; // 默认地址
    } else {
        front_addresses_ = front_addresses;
    }
    
    // 根据官方建议，使用空字符串让CTP API自动处理流文件路径
    // 这是解决"can not open CFlow file"错误的标准方法
    flow_path_ = flow_path.empty() ? "" : flow_path;
    
    // 创建API实例
    return create_api();
}

void TraderApi::release() {
    stop_query_thread_ = true;
    if (query_thread_.joinable()) {
        query_thread_.join();
    }
    
    if (api_) {
        api_->Release();
        api_ = nullptr;
    }
    
    state_ = TradeState::DISCONNECTED;
}

bool TraderApi::connect() {
    if (api_) {
        return false;
    }
    
    // 创建API实例 - 使用空路径避免CFlow文件错误
    api_ = CThostFtdcTraderApi::CreateFtdcTraderApi(flow_path_.c_str());
    if (!api_) {
        return false;
    }
    
    // 注册回调
    api_->RegisterSpi(this);
    
    // 注册前置地址
    for (const auto& addr : front_addresses_) {
        api_->RegisterFront(const_cast<char*>(addr.c_str()));
    }
    
    // 订阅私有流
    api_->SubscribePrivateTopic(THOST_TERT_QUICK);
    api_->SubscribePublicTopic(THOST_TERT_QUICK);
    
    // 初始化
    api_->Init();
    
    state_ = TradeState::CONNECTING;
    
    // 启动查询线程
    stop_query_thread_ = false;
    query_thread_ = std::thread(&TraderApi::process_query_queue, this);
    
    return true;
}

void TraderApi::disconnect() {
    if (api_) {
        api_->RegisterSpi(nullptr);
    }
    state_ = TradeState::DISCONNECTED;
}

bool TraderApi::is_connected() const {
    return state_ >= TradeState::CONNECTED;
}

bool TraderApi::login(const std::string& broker_id,
                     const std::string& user_id,
                     const std::string& password,
                     const std::string& app_id,
                     const std::string& auth_code) {
    broker_id_ = broker_id;
    user_id_ = user_id;
    password_ = password;
    app_id_ = app_id;
    auth_code_ = auth_code;
    
    if (state_ != TradeState::CONNECTED) {
        return false;
    }
    
    // 认证
    if (!app_id_.empty() && !auth_code_.empty()) {
        CThostFtdcReqAuthenticateField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.UserID, user_id_, sizeof(req.UserID));
        safe_copy_string(req.AppID, app_id_, sizeof(req.AppID));
        safe_copy_string(req.AuthCode, auth_code_, sizeof(req.AuthCode));
        
        int ret = api_->ReqAuthenticate(&req, generate_request_id());
        if (ret != 0) {
            return false;
        }
        
        state_ = TradeState::AUTHENTICATING;
    } else {
        // 直接登录
        CThostFtdcReqUserLoginField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.UserID, user_id_, sizeof(req.UserID));
        safe_copy_string(req.Password, password_, sizeof(req.Password));
        
        int ret = api_->ReqUserLogin(&req, generate_request_id());
        if (ret != 0) {
            return false;
        }
        
        state_ = TradeState::LOGGING_IN;
    }
    
    return true;
}

void TraderApi::logout() {
    if (state_ < TradeState::LOGGED_IN) {
        return;
    }
    
    CThostFtdcUserLogoutField req = {};
    safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
    safe_copy_string(req.UserID, user_id_, sizeof(req.UserID));
    
    api_->ReqUserLogout(&req, generate_request_id());
}

std::string TraderApi::insert_order(const OrderRequest& request) {
    if (state_ != TradeState::READY) {
        return "";
    }
    
    CThostFtdcInputOrderField req = {};
    
    // 填充订单字段
    safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
    safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
    safe_copy_string(req.InstrumentID, request.instrument_id, sizeof(req.InstrumentID));
    
    std::string order_ref = generate_order_ref();
    safe_copy_string(req.OrderRef, order_ref, sizeof(req.OrderRef));
    
    req.Direction = request.direction;
    req.CombOffsetFlag[0] = request.offset_flag;
    req.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
    req.LimitPrice = request.limit_price;
    req.VolumeTotalOriginal = request.volume;
    req.TimeCondition = request.time_condition;
    req.VolumeCondition = THOST_FTDC_VC_AV;
    req.MinVolume = 1;
    req.ContingentCondition = THOST_FTDC_CC_Immediately;
    req.OrderPriceType = request.price_type;
    req.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
    req.IsAutoSuspend = 0;
    req.UserForceClose = 0;
    
    int ret = api_->ReqOrderInsert(&req, generate_request_id());
    if (ret == 0) {
        total_orders_++;
        return order_ref;
    }
    
    return "";
}

bool TraderApi::cancel_order(const CancelRequest& request) {
    if (state_ != TradeState::READY) {
        return false;
    }
    
    CThostFtdcInputOrderActionField req = {};
    
    safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
    safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
    safe_copy_string(req.OrderRef, request.order_ref, sizeof(req.OrderRef));
    req.FrontID = request.front_id;
    req.SessionID = request.session_id;
    req.ActionFlag = THOST_FTDC_AF_Delete;
    
    int ret = api_->ReqOrderAction(&req, generate_request_id());
    return ret == 0;
}

bool TraderApi::query_account() {
    add_query_task([this]() {
        CThostFtdcQryTradingAccountField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
        api_->ReqQryTradingAccount(&req, generate_request_id());
    });
    return true;
}

bool TraderApi::query_positions() {
    add_query_task([this]() {
        CThostFtdcQryInvestorPositionField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
        api_->ReqQryInvestorPosition(&req, generate_request_id());
    });
    return true;
}

bool TraderApi::query_orders() {
    add_query_task([this]() {
        CThostFtdcQryOrderField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
        api_->ReqQryOrder(&req, generate_request_id());
    });
    return true;
}

bool TraderApi::query_trades() {
    add_query_task([this]() {
        CThostFtdcQryTradeField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
        api_->ReqQryTrade(&req, generate_request_id());
    });
    return true;
}

void TraderApi::set_callback(std::shared_ptr<ITraderCallback> callback) {
    callback_ = callback;
}

// CTP回调函数实现
void TraderApi::OnFrontConnected() {
    state_ = TradeState::CONNECTED;
    if (callback_) {
        callback_->on_connected();
    }
}

void TraderApi::OnFrontDisconnected(int nReason) {
    state_ = TradeState::DISCONNECTED;
    if (callback_) {
        callback_->on_disconnected(nReason);
    }
}

void TraderApi::OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField,
                                 CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo)) {
        state_ = TradeState::AUTHENTICATED;
        
        // 发送登录请求
        CThostFtdcReqUserLoginField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.UserID, user_id_, sizeof(req.UserID));
        safe_copy_string(req.Password, password_, sizeof(req.Password));
        
        api_->ReqUserLogin(&req, generate_request_id());
        state_ = TradeState::LOGGING_IN;
    } else {
        handle_error(pRspInfo, "认证");
    }
}

void TraderApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,
                              CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo)) {
        state_ = TradeState::LOGGED_IN;
        
        if (pRspUserLogin) {
            front_id_ = pRspUserLogin->FrontID;
            session_id_ = pRspUserLogin->SessionID;
        }
        
        // 确认结算信息
        CThostFtdcSettlementInfoConfirmField req = {};
        safe_copy_string(req.BrokerID, broker_id_, sizeof(req.BrokerID));
        safe_copy_string(req.InvestorID, user_id_, sizeof(req.InvestorID));
        
        api_->ReqSettlementInfoConfirm(&req, generate_request_id());
        state_ = TradeState::CONFIRMING;
        
        if (callback_) {
            callback_->on_login_success();
        }
    } else {
        handle_error(pRspInfo, "登录");
        if (callback_) {
            callback_->on_login_failed(pRspInfo ? pRspInfo->ErrorMsg : "未知错误");
        }
    }
}

void TraderApi::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout,
                               CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    state_ = TradeState::CONNECTED;
}

void TraderApi::OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm,
                                          CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo)) {
        state_ = TradeState::READY;
    }
}

void TraderApi::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder,
                                CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (is_error_response(pRspInfo)) {
        handle_error(pRspInfo, "报单");
        if (callback_) {
            callback_->on_order_error(pRspInfo ? pRspInfo->ErrorMsg : "报单失败");
        }
    }
}

void TraderApi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction,
                                CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (is_error_response(pRspInfo)) {
        handle_error(pRspInfo, "撤单");
    }
}

void TraderApi::OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount,
                                      CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo) && pTradingAccount) {
        AccountInfo account = convert_account(pTradingAccount);
        account_info_ = account;
        
        if (callback_) {
            callback_->on_account_info(account);
        }
    }
}

void TraderApi::OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition,
                                        CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo) && pInvestorPosition) {
        PositionInfo position = convert_position(pInvestorPosition);
        positions_[position.instrument_id] = position;
        
        if (callback_) {
            callback_->on_position_info(position);
        }
    }
}

void TraderApi::OnRspQryOrder(CThostFtdcOrderField *pOrder,
                             CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo) && pOrder) {
        OrderInfo order = convert_order(pOrder);
        orders_[order.order_ref] = order;
    }
}

void TraderApi::OnRspQryTrade(CThostFtdcTradeField *pTrade,
                             CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    if (!is_error_response(pRspInfo) && pTrade) {
        TradeInfo trade = convert_trade(pTrade);
        if (callback_) {
            callback_->on_trade(trade);
        }
    }
}

void TraderApi::OnRtnOrder(CThostFtdcOrderField *pOrder) {
    if (pOrder) {
        OrderInfo order = convert_order(pOrder);
        orders_[order.order_ref] = order;
        
        if (callback_) {
            callback_->on_order_update(order);
        }
    }
}

void TraderApi::OnRtnTrade(CThostFtdcTradeField *pTrade) {
    if (pTrade) {
        TradeInfo trade = convert_trade(pTrade);
        total_trades_++;
        
        if (callback_) {
            callback_->on_trade(trade);
        }
    }
}

void TraderApi::OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder,
                                   CThostFtdcRspInfoField *pRspInfo) {
    handle_error(pRspInfo, "报单错误");
    if (callback_) {
        callback_->on_order_error(pRspInfo ? pRspInfo->ErrorMsg : "报单错误");
    }
}

void TraderApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
    handle_error(pRspInfo, "系统错误");
    if (callback_) {
        callback_->on_error(pRspInfo ? pRspInfo->ErrorID : -1,
                           pRspInfo ? pRspInfo->ErrorMsg : "未知错误");
    }
}

// 内部辅助函数
int TraderApi::generate_request_id() {
    return ++request_id_;
}

std::string TraderApi::generate_order_ref() {
    return std::to_string(++order_ref_);
}

bool TraderApi::is_error_response(CThostFtdcRspInfoField *pRspInfo) {
    return pRspInfo && pRspInfo->ErrorID != 0;
}

void TraderApi::handle_error(CThostFtdcRspInfoField *pRspInfo, const std::string& operation) {
    if (pRspInfo) {
        std::cerr << operation << "失败: " << pRspInfo->ErrorID << " " << pRspInfo->ErrorMsg << std::endl;
    }
}

OrderInfo TraderApi::convert_order(const CThostFtdcOrderField* pOrder) {
    OrderInfo order;
    if (pOrder) {
        order.instrument_id = pOrder->InstrumentID;
        order.order_ref = pOrder->OrderRef;
        order.order_sys_id = pOrder->OrderSysID;
        order.direction = pOrder->Direction;
        order.offset_flag = pOrder->CombOffsetFlag[0];
        order.limit_price = pOrder->LimitPrice;
        order.volume_total_original = pOrder->VolumeTotalOriginal;
        order.volume_traded = pOrder->VolumeTraded;
        order.volume_left = pOrder->VolumeTotal;
        order.order_status = pOrder->OrderStatus;
        order.status_msg = pOrder->StatusMsg;
        order.insert_time = pOrder->InsertTime;
        order.update_time = pOrder->UpdateTime;
        order.front_id = pOrder->FrontID;
        order.session_id = pOrder->SessionID;
    }
    return order;
}

TradeInfo TraderApi::convert_trade(const CThostFtdcTradeField* pTrade) {
    TradeInfo trade;
    if (pTrade) {
        trade.trade_id = pTrade->TradeID;
        trade.order_ref = pTrade->OrderRef;
        trade.order_sys_id = pTrade->OrderSysID;
        trade.instrument_id = pTrade->InstrumentID;
        trade.direction = pTrade->Direction;
        trade.offset_flag = pTrade->OffsetFlag;
        trade.price = pTrade->Price;
        trade.volume = pTrade->Volume;
        trade.trade_time = pTrade->TradeTime;
    }
    return trade;
}

PositionInfo TraderApi::convert_position(const CThostFtdcInvestorPositionField* pPosition) {
    PositionInfo position;
    if (pPosition) {
        position.instrument_id = pPosition->InstrumentID;
        position.pos_direction = pPosition->PosiDirection;
        position.position = pPosition->Position;
        position.position_today = pPosition->TodayPosition;
        position.position_yesterday = pPosition->YdPosition;
        position.open_cost = pPosition->OpenCost;
        position.position_cost = pPosition->PositionCost;
        position.margin = pPosition->UseMargin;
        position.profit = pPosition->PositionProfit;
    }
    return position;
}

AccountInfo TraderApi::convert_account(const CThostFtdcTradingAccountField* pAccount) {
    AccountInfo account;
    if (pAccount) {
        account.account_id = pAccount->AccountID;
        account.pre_balance = pAccount->PreBalance;
        account.balance = pAccount->Balance;
        account.available = pAccount->Available;
        account.margin = pAccount->CurrMargin;
        account.profit = pAccount->PositionProfit;
        account.commission = pAccount->Commission;
    }
    return account;
}

void TraderApi::process_query_queue() {
    while (!stop_query_thread_) {
        // 简化的查询队列处理
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

void TraderApi::add_query_task(const std::function<void()>& task) {
    // 简化实现：直接执行任务
    task();
}

bool TraderApi::create_api() {
    if (api_) {
        return true; // 已经初始化
    }
    
    // 创建CTP API实例 - 使用空路径避免CFlow文件错误
    api_ = CThostFtdcTraderApi::CreateFtdcTraderApi(flow_path_.c_str());
    if (!api_) {
        std::cerr << "Failed to create CTP Trader API" << std::endl;
        return false;
    }
    
    // 注册回调
    api_->RegisterSpi(this);
    
    // 订阅公有流和私有流
    api_->SubscribePublicTopic(THOST_TERT_RESTART);
    api_->SubscribePrivateTopic(THOST_TERT_RESTART);
    
    return true;
}

} // namespace ctp_api 